package com.base.api.pubg.crawl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.base.api.pubg.enums.PUBG;
import com.base.utils.RedisServer;
import com.base.vo.pubg.Jsondata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

/**
 * 下载线程
 *
 * @author: junw
 * @date: 2018/5/22 17:33
 */
public class DownloadThread implements Runnable {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private DownloadConfig downloadConfig;

    public DownloadThread(DownloadConfig downloadConfig) {
        this.downloadConfig = downloadConfig;
    }

    @Override
    public void run() {
        RedisServer redisServer = downloadConfig.getRedisServer();
        while (redisServer.listSize(PUBG.QUEUE.getDesc()) > 0 && !downloadConfig.isClose()) {
            Object value = null;
            try {
                // 从队列弹出一个值并放到暂存队列
                value = redisServer.brpoplpush(PUBG.QUEUE.getDesc(), PUBG.TEMPQUEUE.getDesc());
                if (value == null) {
                    continue;
                }
                // 业务逻辑
                operation(value.toString());
            } catch (Exception e) {
                logger.error("下载子线程异常：" + e.getMessage());
                // 将值放回队列
                redisServer.lpush(PUBG.QUEUE.getDesc(), value);
            }
            // 业务完成将暂存队列中的值删除
            redisServer.removeListValue(PUBG.TEMPQUEUE.getDesc(), 1, value);
        }
    }

    /**
     * 下载任务逻辑
     *
     * @param id
     * @throws IOException
     */
    public void operation(String id) throws IOException {
        String[] parameter = id.split(",");
        if (duplicate(parameter[0])) {
            return;
        }
        JSONObject matcheInfo = downloadConfig.getPubgHttpClient().getMatcheInfo(parameter[0]);
        JSONObject attributesObject = matcheInfo.getJSONObject("data").getJSONObject("attributes");
        Iterator<Object> matcheInfoIterator = matcheInfo.getJSONArray("included").iterator();
        while (matcheInfoIterator.hasNext()) {
            JSONObject matcheInfoObject = (JSONObject) matcheInfoIterator.next();
            if (StringUtils.equals(matcheInfoObject.getString("type"), "asset")) {
                JSONArray telemetry = downloadConfig.getPubgHttpClient().getTelemetry(matcheInfoObject.getJSONObject("attributes").getString("URL"));
                Jsondata jsondata = new Jsondata();
                jsondata.setName(parameter[1]);
                jsondata.setCreatedat(attributesObject.getString("createdAt"));
                jsondata.setGamemode(attributesObject.getString("gameMode"));
                jsondata.setMapname(attributesObject.getString("mapName"));
                jsondata.setShardid(attributesObject.getString("shardId"));
                jsondata.setDuration(attributesObject.getString("duration"));
                jsondata.setJson(telemetry.toJSONString());
                List<Map<String, String>> list = new ArrayList<>();
                parseIn(telemetry, list);
                downloadConfig.getiPubgDataTransactionService().insertData(list, jsondata);
                logger.info("新增一条-" + parameter[1]);
            }
        }
    }

    /**
     * 检查数据是否重复
     *
     * @param matchid 比赛ID
     * @return 是否重复
     */
    private boolean duplicate(String matchid) {
        if (downloadConfig.getJsondataMapper().selectCount(matchid) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 将json数据放入list
     *
     * @param jsonArray json数组数据
     * @param list      存放数据的list
     */
    public void parseIn(JSONArray jsonArray, List<Map<String, String>> list) {
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext()) {
            Map<String, String> map = new HashMap<>(16);
            JSONObject jsonObject = (JSONObject) iterator.next();
            parse(jsonObject, null, map);
            list.add(map);
        }
    }

    /**
     * 递归去便利json数据
     *
     * @param jsonObject json对象
     * @param parent     父节点
     * @param map        存放数据的map
     */
    public void parse(JSONObject jsonObject, String parent, Map<String, String> map) {
        Set<Map.Entry<String, Object>> entrySet = jsonObject.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            if (entry.getValue() instanceof JSONObject) {
                if (!StringUtils.isEmpty(parent)) {
                    parse((JSONObject) entry.getValue(), parent + "_" + entry.getKey(), map);
                } else {
                    parse((JSONObject) entry.getValue(), entry.getKey(), map);
                }
            } else {
                if (!StringUtils.isEmpty(parent)) {
                    map.put(parent + "_" + entry.getKey(), entry.getValue().toString());
                } else {
                    map.put(entry.getKey(), entry.getValue().toString());
                }
            }
        }
    }

}
